/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Editor.java
 *
 * Created on Dec 1, 2011, 10:54:34 PM
 */
package jobscheduling.gui;

import java.awt.event.KeyEvent;
import jobscheduling.model.Job;
import jobscheduling.model.Problem;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;

/**
 *
 * @author bursant
 */
public class Editor extends javax.swing.JFrame {
    private Problem _problem;
    private int _jobChoosen;
    private int _taskChoosen;
    private int _id;
    private javax.swing.JList _inputList;
    private MouseListener _jobListListener;
    
    /** Creates new form Editor */
    public Editor(javax.swing.JList inputList, int id) {
        _jobListListener = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e){
                if (e.getClickCount() == 1) {
                    _jobChoosen = jobsList.locationToIndex(e.getPoint());
                    setTaskList(_jobChoosen);  
                }
            }
        };
        DefaultListModel model = (DefaultListModel)inputList.getModel();
        _problem = new Problem((Problem)model.getElementAt(id));
        _id = id;
        _inputList = inputList;
        initComponents();
        jobsList.setModel(new DefaultListModel());
        taskList.setModel(new DefaultListModel());
        durationTextField.setEditable(false);
        jobsList.addMouseListener(_jobListListener);
        initContent();
    }
    

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        nameLabel = new javax.swing.JLabel();
        jobsLabel = new javax.swing.JLabel();
        machinesLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        buttons = new javax.swing.JPanel();
        cancel = new javax.swing.JButton();
        clear = new javax.swing.JButton();
        ok = new javax.swing.JButton();
        jobsScrollPane = new javax.swing.JScrollPane();
        jobsList = new javax.swing.JList();
        taskListScrollPane = new javax.swing.JScrollPane();
        taskList = new javax.swing.JList();
        durationLabel = new javax.swing.JLabel();
        durationTextField = new javax.swing.JTextField();
        jobsTextField = new javax.swing.JTextField();
        machinesTextField = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Input Editor");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        nameLabel.setText("Name:");

        jobsLabel.setText("Jobs:");

        machinesLabel.setText("Machines/Tasks:");

        nameTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nameTextFieldActionPerformed(evt);
            }
        });
        nameTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                nameTextFieldFocusLost(evt);
            }
        });

        cancel.setText("Cancel");
        cancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelActionPerformed(evt);
            }
        });

        clear.setText("Clear");
        clear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearActionPerformed(evt);
            }
        });

        ok.setText("OK");
        ok.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                okActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout buttonsLayout = new javax.swing.GroupLayout(buttons);
        buttons.setLayout(buttonsLayout);
        buttonsLayout.setHorizontalGroup(
            buttonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(buttonsLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(clear, javax.swing.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ok, javax.swing.GroupLayout.DEFAULT_SIZE, 207, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cancel, javax.swing.GroupLayout.DEFAULT_SIZE, 209, Short.MAX_VALUE)
                .addContainerGap())
        );
        buttonsLayout.setVerticalGroup(
            buttonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(buttonsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(buttonsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(ok)
                    .addComponent(cancel)
                    .addComponent(clear))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jobsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jobsList.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jobsListKeyPressed(evt);
            }
        });
        jobsScrollPane.setViewportView(jobsList);

        taskList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        taskList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                taskListMouseClicked(evt);
            }
        });
        taskList.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                taskListFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                taskListFocusLost(evt);
            }
        });
        taskList.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                taskListKeyPressed(evt);
            }
        });
        taskListScrollPane.setViewportView(taskList);

        durationLabel.setText("Duration:");

        durationTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                durationTextFieldActionPerformed(evt);
            }
        });
        durationTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                durationTextFieldFocusLost(evt);
            }
        });

        jobsTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jobsTextFieldActionPerformed(evt);
            }
        });
        jobsTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                jobsTextFieldFocusLost(evt);
            }
        });

        machinesTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                machinesTextFieldActionPerformed(evt);
            }
        });
        machinesTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                machinesTextFieldFocusLost(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addComponent(nameLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jobsLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jobsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jobsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGap(2, 2, 2)
                                .addComponent(taskListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(10, 10, 10)
                                .addComponent(durationLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(durationTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 268, Short.MAX_VALUE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(machinesLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(machinesTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addComponent(buttons, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jobsTextField, machinesTextField, nameTextField});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(nameTextField)
                        .addComponent(nameLabel)
                        .addComponent(jobsLabel)
                        .addComponent(jobsTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(machinesLabel)
                        .addComponent(machinesTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(taskListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(durationTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(durationLabel)))
                    .addComponent(jobsScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(buttons, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /** Initalize content at the beginning and after setting number of jobs
     * or number of machines. 
     */
    private void initContent(){
        jobsTextField.setText(Integer.toString(_problem.getJobs().length));
        machinesTextField.setText(Integer.toString(_problem.getMachinesNumber()));
        nameTextField.setText(_problem.getName());
        DefaultListModel taskModel = (DefaultListModel)taskList.getModel();
        DefaultListModel jobModel = (DefaultListModel)jobsList.getModel();
        taskModel.clear();
        jobModel.clear();
        for(int i = 0; i < _problem.getJobs().length; i++){
           jobModel.addElement(_problem.getJobs()[i]);
        }
    }

    /**
     * Updates lists of tasks for selected job.
     * @param jobIndex idnex of selected job in a jobs list
     */
    private void setTaskList(int jobIndex){
        DefaultListModel jobModel = (DefaultListModel)jobsList.getModel();
        if(jobModel.getSize() != 0){
            Job job = (Job)jobModel.get(jobIndex);
            DefaultListModel model = (DefaultListModel)taskList.getModel();
            model.clear();
            for(int i = 0; i < job.tasks.length; i++)
                model.addElement(job.tasks[i]);
        }
    }
    
    private void jobsNumberChanged(){
        try {
            int newJobsNumber = Integer.parseInt(jobsTextField.getText());
            if (newJobsNumber >= 1){
                _problem.setJobsNumber(newJobsNumber);
            }
        } catch (NumberFormatException e){ }
        initContent();
    }
    
    private void machineNumberChanged(){
        try {
            int newMachineNumber = Integer.parseInt(machinesTextField.getText());
            if (newMachineNumber >= 1){
                _problem.setMachinesNumber(newMachineNumber);
            }
        } catch (NumberFormatException e){ }
        initContent();
    }
    
    private void durationChanged(){
        DefaultListModel taskModel = (DefaultListModel)taskList.getModel();
        DefaultListModel jobModel = (DefaultListModel)jobsList.getModel();
        if(taskModel.getSize() != 0 && jobModel.getSize() != 0){
            int value;
            try{
                value = Integer.parseInt(durationTextField.getText());
            }catch(NumberFormatException e){
                return;
            }
            for(int i = 0; i < taskModel.getSize(); i++)
                if(taskList.isSelectedIndex(i))
                    _problem.setTask(_jobChoosen, i, value);
            setTaskList(_jobChoosen);
        }
    }

    /**
     * Updates number of jobs according to data form jobstextfield.
     * @param evt 
     */
private void durationTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_durationTextFieldActionPerformed
    durationChanged();
}//GEN-LAST:event_durationTextFieldActionPerformed

private void clearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearActionPerformed
    _problem.setMachinesNumber(0);
    _problem.setJobs(new Job[0]);
    initContent();
}//GEN-LAST:event_clearActionPerformed

private void okActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okActionPerformed
    DefaultListModel model = (DefaultListModel)_inputList.getModel();
    model.setElementAt(_problem, _id);
    this.dispose();
    
}//GEN-LAST:event_okActionPerformed

private void cancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelActionPerformed
    this.dispose();
}//GEN-LAST:event_cancelActionPerformed

private void nameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameTextFieldActionPerformed
    _problem.setName(nameTextField.getText());
}//GEN-LAST:event_nameTextFieldActionPerformed

private void jobsTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jobsTextFieldActionPerformed
    jobsNumberChanged();
}//GEN-LAST:event_jobsTextFieldActionPerformed

private void machinesTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_machinesTextFieldActionPerformed
    machineNumberChanged();
}//GEN-LAST:event_machinesTextFieldActionPerformed

private void jobsTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jobsTextFieldFocusLost
    jobsNumberChanged();
}//GEN-LAST:event_jobsTextFieldFocusLost

private void machinesTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_machinesTextFieldFocusLost
    machineNumberChanged();
}//GEN-LAST:event_machinesTextFieldFocusLost

private void nameTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_nameTextFieldFocusLost
    _problem.setName(nameTextField.getText());
}//GEN-LAST:event_nameTextFieldFocusLost

private void durationTextFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_durationTextFieldFocusLost
    if(taskList.getSelectedIndex() == -1){
        durationTextField.setText(" ");
        durationTextField.setEditable(false);
    }
    else
    {
        DefaultListModel taskModel = (DefaultListModel)taskList.getModel();
        DefaultListModel jobModel = (DefaultListModel)jobsList.getModel();
        if(taskModel.getSize() != 0 && jobModel.getSize() != 0){
            int value;
            try{
                value = Integer.parseInt(durationTextField.getText());
            }catch(NumberFormatException e){
                return;
            }
            _problem.setTask(_jobChoosen, _taskChoosen, value);
            setTaskList(_jobChoosen);
        }
    }
}//GEN-LAST:event_durationTextFieldFocusLost

private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
// TODO add your handling code here:
}//GEN-LAST:event_formWindowClosed

private void jobsListKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jobsListKeyPressed
    int index = jobsList.getSelectedIndex();
    if(evt.getKeyCode() == KeyEvent.VK_UP){
        _jobChoosen = index-1 > 0 ? index-1 : 0;
        setTaskList(_jobChoosen);
    }
    if(evt.getKeyCode() == KeyEvent.VK_DOWN){
        _jobChoosen = index+1 < jobsList.getModel().getSize()-1 ? index+1 : jobsList.getModel().getSize()-1;
        setTaskList(_jobChoosen);
    }
    return;
}//GEN-LAST:event_jobsListKeyPressed

private void taskListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_taskListMouseClicked
    if(taskList.getModel().getSize() == 0)
        return;
    _taskChoosen = taskList.locationToIndex(evt.getPoint());
    Integer value = (Integer)taskList.getModel().getElementAt(_taskChoosen);
    durationTextField.setText(value.toString());    
}//GEN-LAST:event_taskListMouseClicked

private void taskListFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_taskListFocusGained
    durationTextField.setEditable(true);
}//GEN-LAST:event_taskListFocusGained

private void taskListFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_taskListFocusLost
    if(taskList.getSelectedIndex() == -1){
        durationTextField.setText(" ");
        durationTextField.setEditable(false);
    }
}//GEN-LAST:event_taskListFocusLost

private void taskListKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_taskListKeyPressed
    int index = taskList.getSelectedIndex();
    if(evt.getKeyCode() == KeyEvent.VK_UP){
        _taskChoosen = index-1 > 0 ? index-1 : 0;
    }
    if(evt.getKeyCode() == KeyEvent.VK_DOWN){
        _taskChoosen = index+1 < taskList.getModel().getSize()-1 ? index+1 : taskList.getModel().getSize()-1;
    }
    durationTextField.setText(Integer.toString((Integer)taskList.getModel().getElementAt(_taskChoosen)));
    return;
}//GEN-LAST:event_taskListKeyPressed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel buttons;
    private javax.swing.JButton cancel;
    private javax.swing.JButton clear;
    private javax.swing.JLabel durationLabel;
    private javax.swing.JTextField durationTextField;
    private javax.swing.JLabel jobsLabel;
    private javax.swing.JList jobsList;
    private javax.swing.JScrollPane jobsScrollPane;
    private javax.swing.JTextField jobsTextField;
    private javax.swing.JLabel machinesLabel;
    private javax.swing.JTextField machinesTextField;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JButton ok;
    private javax.swing.JList taskList;
    private javax.swing.JScrollPane taskListScrollPane;
    // End of variables declaration//GEN-END:variables
}
